﻿/* Original Author:  Dominick O'Dierno
 * Date: 4/4/2008   odiernod@gmail.com     --Originally intended for use with DOMercury:  http://www.odierno.com/domercury
 * Description: Provides an interface to the DOMercury core functionality to plugins.
 * 
 * --CHANGELOG--
 * 
 * */

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using DOMercury.Managers;
using DOMercury.Interfaces;
using DOMercury.Items;


namespace DOMercury
{
    /// <summary>
    /// The DOMercury Engine Core API. This Gets handed to the DOMercuryEngineInterface to allow EngineCore Functionality to DOMercury Plugins
    /// </summary>
    public class DOMercuryEngineFacade : IDOMercury
    {
        public DOMercuryEngineFacade()
        {
           
        }

        private AutoCompleteMode AutoCompleteMode;
        private AutoCompleteSource AutoCompleteSource;
        private AutoCompleteStringCollection CustomSource;

        #region IDOMercury Members
        /// <summary>
        /// Returns the current DOMercury Index to the main DOMercury index
        /// </summary>
        public void ReturnMainIndex()
        {
            IndexManager.ReturnMainIndex();
        }

        /// <summary>
        /// Sets the proper Autocomplete source configuration for a search textbox
        /// </summary>
        /// <param name="type">the ItemType of the currently selected item</param>
        /// <returns></returns>
        public AutoCompleteSource ItemAutoCompleteSource(string type)
        {
            return IndexManager.ChangeItemAutoCompleteSource(type);
        }

        /// <summary>
        /// Sets the proper Autocomplete source configuration for a search textbox
        /// </summary>
        /// <param name="Parameters">A list of possible IItem parameters</param>
        /// <param name="AutoCompleteMode">The suggested autocomplete mode for a parameters textbox</param>
        /// <param name="AutoCompleteSource">The suggested autocompletesource for a parameters textbox</param>
        /// <param name="CustomSource">A possible custom autocomplete source for a parameters textbox</param>
        /// <param name="pType">The Parameter Type of the currently selected action</param>
        /// <param name="iType">The Item Type of the currently selected Item</param>
        public void ChangeParametersAutoCompleteSource(out List<IItem> Parameters, out AutoCompleteMode AutoCompleteMode, out AutoCompleteSource AutoCompleteSource, out AutoCompleteStringCollection CustomSource, string pType, string iType)
        {
            IndexManager.ChangeParametersAutoCompleteSource(out Parameters, out AutoCompleteMode, out AutoCompleteSource, out CustomSource, pType, iType);
        }

        /// <summary>
        /// Sets the proper Autocomplete source configuration for a search textbox
        /// </summary>
        /// <param name="pType">The Parameter Type of the currently selected action</param>
        /// <param name="iType">The Item Type of the currently selected Item</param>
        /// <returns>default list of IItems to use as the parameters source</returns>
        public List<IItem> ChangeParametersAutoCompleteSource(string pType, string iType)
        {
            List<IItem> Parameters;
            IndexManager.ChangeParametersAutoCompleteSource(out Parameters, out AutoCompleteMode, out AutoCompleteSource, out CustomSource, pType, iType);
            return Parameters;
        }

        /// <summary>
        /// The Parent Item of the current sub index
        /// </summary>
        public IItem ParentItem
        {
            get { return IndexManager.ParentItem; }
        }

        /// <summary>
        /// Dive into a sub index based on the currently selected Item, Action, and Parameters
        /// </summary>
        /// <param name="item">Item to dive into a sub index from</param>
        /// <param name="itemtext">the currently typed search text</param>
        /// <param name="action">The currently selected action</param>
        /// <param name="param">the currently selected parameters. If text, should be a TextItem</param>
        /// <returns></returns>
        public bool SetSubIndex(IItem item, string itemtext, IAction action, IItem param)
        {
            return IndexManager.SetSubIndex(item, itemtext, action, param);
        }

        /// <summary>
        /// Pop the current index to the previous index
        /// </summary>
        public void PreviousIndex()
        {
            IndexManager.PreviousIndex();
        }

        /// <summary>
        /// The search text of the parent index
        /// </summary>
        public string ParentText
        {
            get { return IndexManager.ParentText; }
        }

        /// <summary>
        /// Create a Text Item from the supplied string
        /// </summary>
        /// <param name="itemtext">string to have a TextItem wrapped around</param>
        /// <returns></returns>
        public List<IItem> ProvideTextItem(string itemtext)
        {
            return IndexManager.ProvideTextItem(itemtext);
        }

        /// <summary>
        /// Get results from the current index based on search text
        /// </summary>
        /// <param name="text">The search text with which to retrieve results</param>
        /// <returns>The results</returns>
        public List<IItem> GetItems(string text)
        {
            return IndexManager.GetItems(text);
        }

        /// <summary>
        /// Get results from the Main DOMercury Index based on search text
        /// </summary>
        /// <param name="text">The search text with which to retrieve results</param>
        /// <returns>The results</returns>
        public List<IItem> GetItemsFromMainIndex(string text)
        {
            return IndexManager.MainIndexGetItems(text, ConfigurationManager.MaxResults);
        }

        /// <summary>
        /// Get a certain number of results from the Main DOMercury Index based on search text
        /// </summary>
        /// <param name="text">The search text with which to retrieve results</param>
        /// <param name="NumResults">The maximum number of results returned. NOTE: This function may return less results depending on the possible number of matches</param>
        /// <returns>The results</returns>
        public List<IItem> GetItemsFromMainIndex(string text, int NumResults)
        {
            return IndexManager.MainIndexGetItems(text, NumResults);
        }

        //PluginManager
        /// <summary>
        /// Returns true if the ItemType supports a sub index
        /// </summary>
        /// <param name="type">the ItemType of an IItem</param>
        /// <returns></returns>
        public bool HasSubIndex(string type)
        {
            return PluginManager.HasSubIndex(type);
        }

        //IconManager
        /// <summary>
        /// returns a bitmap based on the DisplayDescription of an IItem, or ActionType of an IAction
        /// </summary>
        /// <param name="filename">The DisplayDescription of an IItem or ActionType of an IAction</param>
        /// <returns></returns>
        public System.Drawing.Bitmap GetIconImage(string filename)
        {
            return IconManager.GetIconImage(filename);
        }

        /// <summary>
        /// returns a bitmap based on the DisplayDescription of an IItem, or ActionType of an IAction, for WPF
        /// </summary>
        /// <param name="filename">The DisplayDescription of an IItem or ActionType of an IAction</param>
        /// <returns></returns>
        public System.Windows.Media.Imaging.BitmapSource GetIconImageWPF(string filename)
        {
            System.Drawing.Bitmap bitmap = GetIconImage(filename);
            if (bitmap != null)
            {
                System.Windows.Media.Imaging.BitmapSource b = 
                System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                bitmap.GetHbitmap(),
                IntPtr.Zero,
                System.Windows.Int32Rect.Empty,
                System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
                b.Freeze();
                return b;
            }
            else
            {
                return null;
            }
        }

        //PathFinder
        /// <summary>
        /// Returns a valid path if found from the path or keyword passed in.  Ex:  mydocs will return the path to the My Documents folder
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public string FindPath(string path)
        {
            return PathFinder.FindPath(path);
        }

        /// <summary>
        /// Returns true if the path passed in is a valid file or network path
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public bool IsPath(string path)
        {
            return PathFinder.IsPath(path);
        }

        //TypeManager
        /// <summary>
        /// Gets all the possible actions referring to an ItemType of an IItem
        /// </summary>
        /// <param name="Type">The ItemType of the IItem to get Actions for</param>
        /// <param name="actions"> a reference to a list of IActions to populate</param>
        /// <returns>true if actions are found for the ItemType</returns>
        public bool GetActions(string Type, ref List<IAction> actions)
        {
            return TypeManager.ItemActions(Type, ref actions);
        }

        //ActionManager
        /// <summary>
        /// Performs the Action on the IItem with the selected parameters
        /// </summary>
        /// <param name="Item">The Item to have the action performed on</param>
        /// <param name="Action">The Action to perform</param>
        /// <param name="specialParams">Any required or optional parameters for the Action</param>
        /// <returns></returns>
        public bool Perform(IItem Item, IAction Action, object specialParams)
        {
            return ActionManager.Perform(Item, Action, specialParams);
        }

        //SelectedItemsGrabber
        /// <summary>
        /// Returns an ItemsList of selected Items from a Windows Explorer Window if a Windows Explorer Window was the active window right before DOMercury was invoked.
        /// </summary>
        /// <returns></returns>
        public ItemsList GetSelectedItems()
        {
            return SelectedItemsGrabber.GetSelectedEnvironmentItems();
        }

        /// <summary>
        /// Disposes and generates a new instance of the current IDOMercuryUserInterface.  This does not Invoke DOMercury
        /// </summary>
        public void RestartInterface()
        {
            
            foreach (IDOMercuryUserInterfaceProvider i in PluginManager.UserInterfaces)
            {
                if (i.Name == ConfigurationManager.CurrentInterface)
                {
                    i.RestartInterface();
                    DOMercuryProgramFlowManager.Instance.ChangeInterface();
                    break;
                }
            }
        }

        /// <summary>
        /// Forces a reinvoke of the DOMercury Interface.  Useful for starting DOMercury with a sub index after an action
        /// </summary>
        public void ReinvokeInterface()
        {
            DOMercuryProgramFlowManager.Instance.MercuryInterface.ActivateForm();
        }

        /// <summary>
        /// Shows the DOMercury Options Form
        /// </summary>
        public void ShowOptions()
        {
            DOMercuryProgramFlowManager.Instance.ShowOptions();
        }

        /// <summary>
        /// Be careful with this one, it will close the application.  This should only be used by UserInterface plugins
        /// </summary>
        public void ExitDOMercury()
        {
            DOMercuryProgramFlowManager.Instance.Exit();
        }

        /// <summary>
        /// Returns true if the current index is the main index.
        /// </summary>
        public bool CurrentIndexIsMainIndex
        {
            get
            {
                return IndexManager.IsMainIndex;
            }
        }
        
        #endregion

        #region IDOMercury Members


        public void ReturnParamMainIndex()
        {
            IndexManager.ReturnParamMainIndex();
        }

        public IItem ParentParamItem
        {
            get { return IndexManager.ParentParamItem; }
        }

        public bool SetParamSubIndex(IItem param, string itemtext, IAction action)
        {
            return IndexManager.SetParamSubIndex(param, itemtext, action);
        }

        public void PreviousParamIndex()
        {
            IndexManager.PreviousParamIndex();
        }

        public string ParentParamText
        {
            get { return IndexManager.ParentParamText; }
        }

        public List<IItem> GetParamItems(string text)
        {
            return IndexManager.GetParamItems(text);
        }

        #endregion
    }
}
